package com.wmjsoft.plugins.nutzplugin.dao

import com.wmjsoft.plugins.nutzplugin.utils.illegalValidation
import org.nutz.dao.Cnd
import org.nutz.dao.Sqls

/**
 * 如果我没有写注释，请提醒我
 * @program: Maternal
 * @description:
 * @author: Mr.Lee
 * @create: 2021-02-20 15:52
 */
class Joiner {

    private var mySql: QueerSql? = null

    private var clazz: Class<*>? = null

    private var clazz1: Class<*>? = null

    private var isJoinAdd = false

    fun init(clazz: Class<*>?, mySql: QueerSql, joinType: String?): Joiner {
        this.mySql = mySql
        this.clazz = clazz
        this.mySql!!.joinSelectString = StringBuilder()
        when (joinType) {
            "LEFT" -> left(clazz)
            "RIGHT" -> right(clazz)
            "INNER" -> inner(clazz)
        }
        return this
    }

    fun where(): Wherer {
        return Wherer(mySql!!)
    }

    fun left(clazz: Class<*>?): Joiner {
        initLeftTableAndRightTable(clazz)
        mySql!!.joinString!!.append(
            " left join " + mySql!!.getTableName(clazz).toString() + " " + mySql!!.getTableName(clazz).toString() + " "
        )
        return this
    }

    fun right(clazz: Class<*>?): Joiner {
        initLeftTableAndRightTable(clazz)
        mySql!!.joinString!!.append(
            " right join " + mySql!!.getTableName(clazz).toString() + " " + mySql!!.getTableName(clazz).toString() + " "
        )
        return this
    }

    fun inner(clazz: Class<*>?): Joiner {
        initLeftTableAndRightTable(clazz)
        mySql!!.joinString!!.append(
            " inner join " + mySql!!.getTableName(clazz).toString() + " " + mySql!!.getTableName(clazz).toString() + " "
        )
        return this
    }

    fun leftAdd(clazz: Class<*>?): Joiner {
        initLeftTableAndRightTable(clazz)
        isJoinAdd = true
        mySql!!.joinString!!.append(
            " left join " + mySql!!.getTableName(clazz).toString() + " " + mySql!!.getTableName(clazz).toString() + " "
        )
        return this
    }

    fun rightAdd(clazz: Class<*>?): Joiner {
        initLeftTableAndRightTable(clazz)
        isJoinAdd = true
        mySql!!.joinString!!.append(
            " right join " + mySql!!.getTableName(clazz).toString() + " " + mySql!!.getTableName(clazz).toString() + " "
        )
        return this
    }

    fun innerAdd(clazz: Class<*>?): Joiner {
        initLeftTableAndRightTable(clazz)
        isJoinAdd = true
        mySql!!.joinString!!.append(
            " inner join " + mySql!!.getTableName(clazz).toString() + " " + mySql!!.getTableName(clazz).toString() + " "
        )
        return this
    }


    fun selectFileds(vararg fileds: String): Joiner{
        for (filed in fileds) {
            mySql!!.joinSelectString!!.append(mySql!!.getTableName(clazz) + "." + filed + ", ")
        }
        return this
    }


    private fun initLeftTableAndRightTable(clazz: Class<*>?) {
        clazz1 = this.clazz
        this.clazz = clazz
    }

    fun on(
        leftTableFiled: String,
        op: String,
        rightTableFiled: String,
        left: Class<*>?,
        right: Class<*>?
    ): Joiner {
        illegalValidation(leftTableFiled,rightTableFiled,op)
        val leftTableName: String = mySql!!.getTableName(left)
        val rightTableName: String = mySql!!.getTableName(right)
        mySql!!.joinString!!.append(" on $leftTableName.$leftTableFiled $op $rightTableName.$rightTableFiled ")
        isJoinAdd = false
        return this
    }

    fun on(leftTableFiled: String, op: String, rightTableFiled: String): Joiner {
        illegalValidation(leftTableFiled,rightTableFiled,op)
        val list = this.tableJoin()
        mySql!!.joinString!!.append(" on ${list[0]}.$leftTableFiled $op ${list[1]}.$rightTableFiled ")
        isJoinAdd = false
        return this
    }



    /**
     * @param leftTableFiled
     * @param op
     * @param rightTableFiled
     * @param sql             特别的条件自行去加，带上join 的表名
     * @return
     */
    fun onAnd(
        leftTableFiled: String,
        op: String,
        rightTableFiled: String,
        ere: Ere
    ): Joiner {
        illegalValidation(leftTableFiled,rightTableFiled,op)
        var list = this.tableJoin()
        mySql!!.joinString!!.append(" on ${list[0]}.$leftTableFiled $op ${list[1]}.$rightTableFiled and ${ereToSql(ere)}")
        isJoinAdd = false
        return this
    }

    fun onOr(
        leftTableFiled: String,
        op: String,
        rightTableFiled: String,
        ere: Ere
    ): Joiner {
        illegalValidation(leftTableFiled,rightTableFiled,op)
        var list = this.tableJoin()
        mySql!!.joinString!!.append(" on ${list[0]}.$leftTableFiled $op ${list[1]}.$rightTableFiled or ${ereToSql(ere)}")
        isJoinAdd = false
        return this
    }

    private fun ereToSql(ere: Ere): String {
        val cnd = Cnd.NEW()
        val c = Cnd.exps(ere.filed, ere.op, ere.value)
        cnd.and(c)
        val sql = Sqls.create(" \$condition").setCondition(cnd)
        var sqlStr = sql.toString()
        sqlStr = sqlStr.substring(sqlStr.indexOf("(")+1,sqlStr.indexOf(")"))
        return sqlStr
    }


    private fun tableJoin(): List<String> {
        var leftTableName: String? = null
        var rightTableName: String? = null
        if (isJoinAdd) {
            leftTableName = mySql!!.getTableName(clazz)
            rightTableName = mySql!!.getTableName(clazz1)
        } else {
            leftTableName = mySql!!.getTableName(clazz)
            rightTableName = mySql!!.getTableName(mySql!!.clazz)
        }
        return listOf<String>(leftTableName,rightTableName)
    }



}